﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VKontakteClient
{
    /// <summary>
    /// Контрол, реализующий отображение аудиозаписи
    /// </summary>
    public partial class AudioControl : UserControl
    {
        /// <summary>
        /// Конструктор контрола
        /// </summary>
        public AudioControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Проверяет скачана ли уже аудиозапись
        /// </summary>
        /// <param name="audio">Аудиозапись для проверки</param>
        /// <param name="callback">Функция, которую надо вызвать по завершению возможно необходимого скачивания, или сразу, когда не надо скачивать</param>
        private static void CheckForDownloaded(Audio audio, SimpleCallback callback)
        {
            System.Threading.ThreadStart t = null;
            Func<string> resolve = () =>
            {
                return "Скачивание аудиозаписи \"" + audio.Name + "\": " + audio.File.ToString();
            };
            if (string.IsNullOrEmpty(audio.File.LocalFileName))
            {
                if (App.IsOffline) return;
                t = () =>
                {
                    var file = audio.File.Uri;
                    while (audio.File.Uri == null) System.Threading.Thread.CurrentThread.Join(200);
                };
            }
            else
            {
                t = () => { };
            }
            App.Scheduler.Enqueue(t, System.Threading.ThreadPriority.Normal, resolve, callback);
        }

        /// <summary>
        /// Метод скачивания выбранной аудиозаписи
        /// </summary>
        private void DownloadFile(object sender, RoutedEventArgs e)
        {
            var X = (this.DataContext as Audio);
            if (X == null) return;
            CheckForDownloaded(X, () =>
            {
                Main.sc.Post((object o) =>
                    {
                        System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog();
                        sfd.AutoUpgradeEnabled = true;
                        sfd.FileName = X.Name + ".mp3";
                        System.Windows.Forms.DialogResult[] dr = { System.Windows.Forms.DialogResult.OK, System.Windows.Forms.DialogResult.Yes };
                        if (dr.Contains(sfd.ShowDialog()))
                        {
                            System.IO.File.Copy(X.File.LocalFileName, sfd.FileName, true);
                        }
                    }, null);
            });
        }

        /// <summary>
        /// Медиаплеер, который используется для проигрывания аудиозаписи
        /// </summary>
        private MediaPlayer _mp = null;

        /// <summary>
        /// Статус плеера
        /// 0 - undef
        /// 1 - играет
        /// 2 - пауза
        /// 3 - завершил
        /// </summary>
        private int _status = 0;

        /// <summary>
        /// Метод запуска воспроизведения файла
        /// </summary>
        private void Play(object sender, RoutedEventArgs e)
        {
            var X = (this.DataContext as Audio);
            if (X == null) return;
            var T = new System.Threading.Thread(() =>
            {
                while (_status == 1 && !Main.IsClosed)
                {
                    Main.sc.Post((object o) =>
                    {
                        PlayBtn.IsEnabled = true;
                        X.Progress = (long)_mp.Position.TotalSeconds;
                    }, null);
                    System.Threading.Thread.Sleep(50);
                }
            });
            if (_mp == null)
            {
                PlayBtn.IsEnabled = false;
                CheckForDownloaded(X, () =>
                {
                    Main.sc.Post((object o) =>
                        {
                            _mp = new MediaPlayer();
                            _mp.Open(X.File.Uri);
                            _mp.MediaEnded += (object q, EventArgs w) => { _status = 3; PlayBtn.Content = ">"; X.Progress = 0; };
                            _mp.Play();
                            _status = 1;
                            PlayBtn.Content = "II";
                            T.Start();
                        }, null);
                });
            }
            else
            {
                Main.sc.Post((object o) =>
                    {
                        if (_status == 1)
                        {
                            _mp.Pause();
                            _status = 2;
                            PlayBtn.Content = ">";
                        } else
                        if (_status == 2)
                        {
                            _mp.Play();
                            _status = 1;
                            PlayBtn.Content = "II";
                        } else
                            if (_status == 3)
                            {
                                _mp.Position = new TimeSpan(0, 0, 0);
                                _mp.Play();
                                _status = 1;
                                PlayBtn.Content = "II";
                            }
                        T.Start();
                    }, null);
            }
        }

        /// <summary>
        /// Метод показа текста песни
        /// </summary>
        private void ShowLyrics(object sender, RoutedEventArgs e)
        {
            var File = this.DataContext as Audio;
            try
            {
                MessageBox.Show(File.Lyrics, File.Name);
            }
            catch (Exception ex)
            {
                DebugLog.DebugException(ex);
            }
        }

        /// <summary>
        /// Метод копирования в буфер обмена ссылки на аудиозапись
        /// </summary>
        private void CopyLink(object sender, RoutedEventArgs e)
        {
            var File = this.DataContext as Audio;
            try
            {
                Clipboard.Clear();
                Clipboard.SetText(File.File.InternetUri.AbsoluteUri, TextDataFormat.Text);
            }
            catch (Exception ex)
            {
                DebugLog.DebugException(ex);
            }
        }

        /// <summary>
        /// Обработчик смены контекста данных
        /// </summary>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var X = this.DataContext as Audio;
            if (X != null)
            {
                ShowLyricsBtn.IsEnabled = !String.IsNullOrEmpty(X.Lyrics);
                ProgressSld.IsEnabled = PlayBtn.IsEnabled = DownloadFileBtn.IsEnabled = !String.IsNullOrEmpty(X.File.LocalFileName) || !App.IsOffline;
            }
        }

        /// <summary>
        /// Обработчик изменения значения ползунка, отображающего прогресс. Криво реализует перемотку.
        /// </summary>
        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (_mp != null && (double)(this.DataContext as Audio).Progress != e.NewValue)
            {
                _mp.Position = new TimeSpan(0, 0, (int)e.NewValue);
            }
        }
    }
}
